// common/http.interceptor.js
import {
	setToken
} from './api'
import store from '@/store';
const codeMessage = {
	404: '您所请求的资源无法找到',
	500: '服务器内部错误，无法完成请求',
};
let TokenInvalidFlag = 0; //token是否失效
// 是否正在刷新的标记
let isRefreshing = false;
// 重试队列，每一项将是一个待执行的函数形式
let retryRequests = []
const install = (Vue, vm) => {
	// 这个配置是一次配置，全局通用的，具体参数见 https://www.uviewui.com/js/http.html
	uni.$u.http.setConfig((config) => {
		// 域名设置
		config.baseURL = process.env.VUE_APP_BASE_URL;
		// 全局header
		config.header = {};
		// 
		config.method = '';
		// 设置为json，返回后会对数据进行一次JSON.parse()
		config.dataType = 'json';
		// 
		config.responseType = 'text';
		// 注：如果局部custom与全局custom有同名属性，则后面的属性会覆盖前面的属性，相当于Object.assign(全局，局部)
		config.custom = {
			// 请求接口展示Loading
			ShowLoading: false,
			// Loading中是否遮罩
			LoadingMask: true,
			// Loading文本
			LoadingText: '正在加载',
			catch: true
		}; // 全局自定义参数默认值
		// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
		config.timeout = 60000;
		// #endif
		// #ifdef APP-PLUS
		// 验证 ssl 证书 仅5+App安卓端支持（HBuilderX 2.3.3+）
		config.sslVerify = true;
		// #endif
		// #ifdef H5
		// 跨域请求时是否携带凭证（cookies）仅H5支持（HBuilderX 2.6.15+）
		config.withCredentials = false;
		// #endif
		// #ifdef APP-PLUS
		// DNS解析时优先使用ipv4 仅 App-Android 支持 (HBuilderX 2.8.0+)
		config.firstIpv4 = false;
		// #endif
		// 局部优先级高于全局，返回当前请求的task,options。请勿在此处修改options。非必填
		// getTask: (task, options) => {
		// 相当于设置了请求超时时间500ms
		//   setTimeout(() => {
		//     task.abort()
		//   }, 500)
		// },
		// 全局自定义验证器。参数为statusCode 且必存在，不用判断空情况。
		config.validateStatus = (statusCode) => { // statusCode 必存在。此处示例为全局默认配置
			return statusCode >= 200 && statusCode < 300
		};
		return config;
	});

	// 请求拦截部分，如配置，每次请求前都会执行
	uni.$u.http.interceptors.request.use((config) => {

		if (config.custom.ShowLoading) {
			uni.showLoading({
				title: config.custom.LoadingText || '正在加载',
				mask: config.custom.LoadingMask || false
			});
		}
		let access_token = uni.getStorageSync('access_token');
		if (access_token && config.url && config.url.indexOf("user/login") == -1 && config.url.indexOf(
				"aliyuncs.com") == -1) {
			config.header['Authorization'] = access_token
		}

		return config;
		// 如果return一个false值，则会取消本次请求
		// if(config.url == '/user/rest') return false; // 取消某次请求
	})

	// 响应拦截，如配置，每次请求结束都会执行本方法
	uni.$u.http.interceptors.response.use((res) => {
		if (res.config.custom.ShowLoading) {
			uni.hideLoading();
		}
		let {
			config
		} = res
		// if 状态码是否正常
		if (res.statusCode == 200) {
			let result = res.data;
			// if 与后台规定的成功码是否正常
			if (result.code == 1) {
				TokenInvalidFlag = 0;
				return result.result || result.data;
			} else if (result.code == 401) {
				if (!isRefreshing) {
					isRefreshing = true
					let refreshToken = uni.getStorageSync('refresh_token');
					if (refreshToken) {
						return setToken({
								refreshToken,
							})
							.then(res => {
								if (res) {
									uni.setStorageSync('access_token', res.access_token);
									uni.setStorageSync('refresh_token', res.refresh_token);
									// 已经刷新了token，将所有队列中的请求进行重试
									retryRequests.forEach(cb => cb(res.access_token))
									// 重试完清空这个队列
									retryRequests = []
									config.baseURL = ''
									config.header.Authorization = res.access_token
									return uni.$u.http.request(config)
								}
							}).finally(() => {
								isRefreshing = false;

							})
					} else {
						console.log("TokenInvalidFlag" + TokenInvalidFlag)
						// message.error('请先登录')
						if (TokenInvalidFlag == 0) {
							TokenInvalidFlag = 1;
							backToLogin();

						}
					}
				} else {
					return new Promise(resolve => {
						// 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
						retryRequests.push(token => {
							config.baseURL = ''
							config.header.Authorization = token
							resolve(uni.$u.http.request(config))
						})
					})
				}

			} else if (result.code == -401) {
				if (TokenInvalidFlag == 0) {
					TokenInvalidFlag = 1;
					backToLogin();

				}

			} else {
				//vm.$u.toast(result.msg);
				uni.showToast({
					title: result.msg,
					icon: 'none'
				})
				// 如果需要catch返回，则进行reject
				if (res.config.custom?.catch) {
					return Promise.reject(result)
				} else {
					// 否则返回一个pending中的promise
					return new Promise(() => {})
				}
			}
		} else {
			let errorMessage = codeMessage[res.statusCode] ? codeMessage[res.statusCode] : res.statusCode;
			// vm.$u.toast(errorMessage);
			uni.showToast({
				title: errorMessage||'发生错误了',
				icon: 'none'
			})
			return Promise.reject(response)
		}
		return false;
	}, (response) => {
		if (response.config.custom.ShowLoading) {
			uni.hideLoading();
		}
		return Promise.reject(response)
	})
}

/**
 * 返回登录页面
 */
async function backToLogin() {
	// 存当前页面的地址
	const currentPage = getCurrentPages()[getCurrentPages().length - 1];
	const params = {};
	console.log('currentPage', currentPage)
	console.log("当前页面的数据" + JSON.stringify(currentPage.__data__))
	// #ifdef H5
	params.route = `/${currentPage.$vm.route}`;
	params.query = currentPage.$vm.$mp && currentPage.$vm.$mp.query;
	// #endif
	// #ifdef MP
	params.route = `/${currentPage.$vm.__route__}`;
	params.query = currentPage.$vm.$mp && currentPage.$vm.$mp.query;
	// #endif
	// #ifdef APP-PLUS
	params.route = `/${currentPage.route}`;
	params.query = currentPage.options;
	// #endif
	/**
	 * 如果存储的地址是index,因为使用自定义自定义底部导航栏tabbar，路由页面会全是index,所以需要存储tabIndex当前tabbar索引，
	 */
	if (params.route == '/pages/index/index') {
		params.tabIndex = currentPage.__data__.tabIndex
	}
	uni.setStorageSync('backToPage', JSON.stringify(params));
	await store.dispatch('Logout').then(() => {
		retryRequests = [];
		isRefreshing = false;
	});
}

export default {
	install
}